from pml import Objects
from pml import PML
from pml import Parser
from pml.Parser.lexer import constants as TokenConstants

class Node(Objects.object.typeobject):
    def __init__(self, name, bp, ep, depth):
        super().__init__(name)
        self.bp = bp
        self.ep = ep
        self.depth = depth

class Name(Node):
    def __init__(self, id: str | None = None, bp=None, ep=None, depth=0):
        super().__init__('name', bp, ep, depth)
        self.id = id
    def __repr__(self):
        return f'Name(id={self.id})'

    def __eq__(self, other):
        return self.id == other.id

    def getObject(self):
        self.methods['__init__'] = self.tp_init
        self.methods['__print__'] = self.tp_print

        return self

    @staticmethod
    def tp_init(frame, this: 'Name', position):
        pass

    @staticmethod
    def tp_print(frame, this: 'Name', position):
        return PML.object.ChangeObject.PMLString_FromStr(this.__repr__())

class Number(Node):
    def __init__(self, type: int = 0, value: str | None = None, bp=None, ep=None, depth=0):
        super().__init__('number', bp, ep, depth)
        self.type = type
        self.value = value

    def __repr__(self):
        return f'Number(type={self.type}, value={repr(self.value)})'

    def __eq__(self, other):
        return self.type == other.obj.type and self.value == other.obj.value

    def getObject(self):
        self.methods['__init__'] = self.tp_init
        self.methods['__print__'] = self.tp_print

        return self

    @staticmethod
    def tp_init(frame, this: 'Name', position):
        pass

    @staticmethod
    def tp_print(frame, this: 'Name', position):
        return PML.object.ChangeObject.PMLString_FromStr(this.__repr__())

class ASTBuilder(Objects.object.typeobject):
    def __init__(self, name, tokens, depth):
        super().__init__(name)
        self.tokens = tokens
        self.token = tokens[tokens.iter].obj
        self.depth = depth

    def getNextToken(self):
        self.token = next(self.tokens).obj
        if self.token.type == TokenConstants.TT_EOF:
            raise StopIteration

    def getLastToken(self):
        self.token = self.tokens.last().obj

    def updateToken(self):
        if self.token.type == TokenConstants.TT_EOF:
            raise StopIteration
        try:
            self.token = self.tokens.value[self.tokens.iter].obj
        except IndexError:
            raise StopIteration
